<template>
  <div class='config-item'>
    <slot v-if="_option.slot" :scope="{ ...scope, row: model }" />
    <!--表单组件-->
    <component ref="objectRef" :style="_option.attrs.style" :class="customClass" v-else :is="_option.tag" :placeholder="$attrs.disabled || $attrs.readonly ? '' : _option.attrs.placeholder" v-model="model" v-bind="{..._option.attrs} || {}" v-on="{..._option.listeners} || {}">
      <template v-if="_option.itemSlot">
        {{ _option.itemSlot }}
      </template>
    </component>
  </div>
</template>
<script>

import basic from './BASIC';

export default {
  components: {},
  props: {
    scope: {
      type: Object,
      defalut: () => ({})
    },
    option: {
      type: Object,
      required: true
    },
    value: {
      default: undefined
    },
    customClass: String
  },
  name: 'configItem',
  model: {
    prop: 'value',
    event: 'on-value-change'
  },
  data () {
    return {
      model: undefined
    };
  },
  created () {

  },
  mounted () {
    this.$nextTick(item => {
      this.$emit('update:objectRef', this.$refs.objectRef);
    })
  },
  methods: {
    computeFormItem (option, model) {
      let tag = option.tag || 'input';
      const { attrs = {}, listeners = {}, ...other } = option;
      // 对应到组件映射表
      const _option = {
        ...basic[tag],
        ...other,
        tag: basic[tag]?.component || tag,
        attrs: {
          ...basic[tag]?.attrs,
          ...attrs,
          defaultProps: attrs.props
        },
        listeners: {
          ...basic[tag]?.listeners,
          ...listeners
        }
      }
      // 获取动态 Attributes
      if (_option.getAttrs) {
        _option.attrs = Object.assign(_option.attrs, _option.getAttrs(model));
      }
      // 处理提示语
      if (!option.attrs?.placeholder) {
        _option.attrs.placeholder = `${_option.attrs.placeholder}${_option.label || ''}`
      }
      return _option;
    },
    handleModelChange () {
      this.$emit('on-value-change', this.model)
    }
  },
  computed: {
    _option () {
      return this.computeFormItem(this.option, this.value)
    }
  },
  watch: {
    _option: {
      handler (item) {
        if (item.slot) return;
        this.model = null;
        if (this.value != null) {
          this.model = this.value;
        } else if (item.value != null) {
          this.model = item.value;
        }
        // 去掉字符串首尾空格
        if (this.model && this.model.constructor == String) {
          this.model = this.model.trim();
        }
        this.handleModelChange();
      },
      immediate: true
    },
    model: {
      handler (val) {
        this.handleModelChange();
      },
      deep: true
    }
  }
}
</script>
<style lang='scss' scoped>
.config-item {

}
</style>
